{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "24eeddf1-b41a-4286-a610-46289d055983",
   "metadata": {},
   "source": [
    "# 一、创建多维数组ndarray\n",
    "- ndarray: 多维数组，具有矢量运算能力，且快速，节省空间\n",
    "- 可对整组数据进行快速运算的表针数学函数，线性代数，随机数生成等功能"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "d319d16c-c578-40ea-8eb2-105ad61526d3",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1 2 3]\n",
      "<class 'numpy.ndarray'>\n",
      "[[1 2 3]\n",
      " [4 5 6]\n",
      " [7 8 9]]\n",
      "<class 'numpy.ndarray'>\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "\n",
    "arr1 = np.array([1,2,3])\n",
    "print(arr1)\n",
    "print(type(arr1))\n",
    "\n",
    "arr2 = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])\n",
    "print(arr2)\n",
    "print(type(arr2))\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "299398f4-f4ff-41db-95a3-6ad77ab7b8d8",
   "metadata": {},
   "source": [
    "# 二、Numpy数组对象ndarray\n",
    "数组属性：ndarray是存储演绎数据类型的多维数组\n",
    "- ndim: 返回int。表示数组的维数\n",
    "- shape: 返回tuple。表示数组的尺寸，对于一维数组，返回列数；对于n行m列的矩阵，形状为（n,m）\n",
    "- size: 返回int。表示数组的元素总数，等于数组形状的乘积。\n",
    "- dtype: 返回data-type。描述数组中元素的类型。\n",
    "- itemsize: 返回int。表示数组的每个元素的大小（以字节为单位）。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "019498a1-7ad6-45a0-9e55-2dc5f156aea3",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1\n",
      "(3,)\n",
      "3\n",
      "int32\n",
      "4\n"
     ]
    }
   ],
   "source": [
    "print(arr1.ndim)\n",
    "print(arr1.shape)\n",
    "print(arr1.size)\n",
    "print(arr1.dtype)\n",
    "print(arr1.itemsize)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9e20ffd3-7d8d-405b-90c7-339e6b0f4147",
   "metadata": {},
   "source": [
    "# 三、认识数组与列表的区别\n",
    "- 数组具有适量运算能力"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "683e0944-4edd-47fe-8d5f-a6b566c716b7",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 4, 9]\n",
      "[1 4 9]\n"
     ]
    }
   ],
   "source": [
    "ls = [1,2,3]\n",
    "arr = np.array(ls)\n",
    "# 现在将数组的每个元素都做平方运算\n",
    "# ls**2 报错\n",
    "arr**2 # 正常运行，结果正确\n",
    "\n",
    "print([i**2 for i in ls])\n",
    "print(arr**2)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "352cbbbb-1818-4eb7-b0e5-c6bc0636eae2",
   "metadata": {},
   "source": [
    "# 四、生成等差数列\n",
    "- np.arange(start, stop, step) 左闭右开，以step为步长，生成等差数列\n",
    "- np.linspace(1, 10, 20),  有闭右闭， 一共生成20个数的等差数列\n",
    "- np.zeros([3,4]),创建全0数组, 3行4列\n",
    "- np.ones([3,4]), 创建全1数组"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "id": "d7d1c320-fd14-45d9-844d-f84033127992",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0 2 4 6 8]\n",
      "[ 0.          0.52631579  1.05263158  1.57894737  2.10526316  2.63157895\n",
      "  3.15789474  3.68421053  4.21052632  4.73684211  5.26315789  5.78947368\n",
      "  6.31578947  6.84210526  7.36842105  7.89473684  8.42105263  8.94736842\n",
      "  9.47368421 10.        ]\n",
      "[[1. 1. 1. 1.]\n",
      " [1. 1. 1. 1.]\n",
      " [1. 1. 1. 1.]]\n"
     ]
    }
   ],
   "source": [
    "arr2 = np.arange(0, 10, 2)\n",
    "arr3 = np.linspace(0,10, 20)\n",
    "print(arr2)\n",
    "print(arr3)\n",
    "arr4 = np.ones([3,4])\n",
    "print(arr4)\n",
    "# help(np.ones)\n",
    "# print(np.zeros())"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2f5e3f6d-29b6-4db7-b292-9122c0dce6b7",
   "metadata": {},
   "source": [
    "## 4.1 help(np.arange)\n",
    "- 查看某个函数的用法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "id": "23383de1-6dfe-4499-83da-5d55010248f3",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "\u001b[1;31mDocstring:\u001b[0m\n",
       "arange([start,] stop[, step,], dtype=None, *, like=None)\n",
       "\n",
       "Return evenly spaced values within a given interval.\n",
       "\n",
       "``arange`` can be called with a varying number of positional arguments:\n",
       "\n",
       "* ``arange(stop)``: Values are generated within the half-open interval\n",
       "  ``[0, stop)`` (in other words, the interval including `start` but\n",
       "  excluding `stop`).\n",
       "* ``arange(start, stop)``: Values are generated within the half-open\n",
       "  interval ``[start, stop)``.\n",
       "* ``arange(start, stop, step)`` Values are generated within the half-open\n",
       "  interval ``[start, stop)``, with spacing between values given by\n",
       "  ``step``.\n",
       "\n",
       "For integer arguments the function is roughly equivalent to the Python\n",
       "built-in :py:class:`range`, but returns an ndarray rather than a ``range``\n",
       "instance.\n",
       "\n",
       "When using a non-integer step, such as 0.1, it is often better to use\n",
       "`numpy.linspace`.\n",
       "\n",
       "See the Warning sections below for more information.\n",
       "\n",
       "Parameters\n",
       "----------\n",
       "start : integer or real, optional\n",
       "    Start of interval.  The interval includes this value.  The default\n",
       "    start value is 0.\n",
       "stop : integer or real\n",
       "    End of interval.  The interval does not include this value, except\n",
       "    in some cases where `step` is not an integer and floating point\n",
       "    round-off affects the length of `out`.\n",
       "step : integer or real, optional\n",
       "    Spacing between values.  For any output `out`, this is the distance\n",
       "    between two adjacent values, ``out[i+1] - out[i]``.  The default\n",
       "    step size is 1.  If `step` is specified as a position argument,\n",
       "    `start` must also be given.\n",
       "dtype : dtype, optional\n",
       "    The type of the output array.  If `dtype` is not given, infer the data\n",
       "    type from the other input arguments.\n",
       "like : array_like, optional\n",
       "    Reference object to allow the creation of arrays which are not\n",
       "    NumPy arrays. If an array-like passed in as ``like`` supports\n",
       "    the ``__array_function__`` protocol, the result will be defined\n",
       "    by it. In this case, it ensures the creation of an array object\n",
       "    compatible with that passed in via this argument.\n",
       "\n",
       "    .. versionadded:: 1.20.0\n",
       "\n",
       "Returns\n",
       "-------\n",
       "arange : ndarray\n",
       "    Array of evenly spaced values.\n",
       "\n",
       "    For floating point arguments, the length of the result is\n",
       "    ``ceil((stop - start)/step)``.  Because of floating point overflow,\n",
       "    this rule may result in the last element of `out` being greater\n",
       "    than `stop`.\n",
       "\n",
       "Warnings\n",
       "--------\n",
       "The length of the output might not be numerically stable.\n",
       "\n",
       "Another stability issue is due to the internal implementation of\n",
       "`numpy.arange`.\n",
       "The actual step value used to populate the array is\n",
       "``dtype(start + step) - dtype(start)`` and not `step`. Precision loss\n",
       "can occur here, due to casting or due to using floating points when\n",
       "`start` is much larger than `step`. This can lead to unexpected\n",
       "behaviour. For example::\n",
       "\n",
       "  >>> np.arange(0, 5, 0.5, dtype=int)\n",
       "  array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0])\n",
       "  >>> np.arange(-3, 3, 0.5, dtype=int)\n",
       "  array([-3, -2, -1,  0,  1,  2,  3,  4,  5,  6,  7,  8])\n",
       "\n",
       "In such cases, the use of `numpy.linspace` should be preferred.\n",
       "\n",
       "The built-in :py:class:`range` generates :std:doc:`Python built-in integers\n",
       "that have arbitrary size <python:c-api/long>`, while `numpy.arange`\n",
       "produces `numpy.int32` or `numpy.int64` numbers. This may result in\n",
       "incorrect results for large integer values::\n",
       "\n",
       "  >>> power = 40\n",
       "  >>> modulo = 10000\n",
       "  >>> x1 = [(n ** power) % modulo for n in range(8)]\n",
       "  >>> x2 = [(n ** power) % modulo for n in np.arange(8)]\n",
       "  >>> print(x1)\n",
       "  [0, 1, 7776, 8801, 6176, 625, 6576, 4001]  # correct\n",
       "  >>> print(x2)\n",
       "  [0, 1, 7776, 7185, 0, 5969, 4816, 3361]  # incorrect\n",
       "\n",
       "See Also\n",
       "--------\n",
       "numpy.linspace : Evenly spaced numbers with careful handling of endpoints.\n",
       "numpy.ogrid: Arrays of evenly spaced numbers in N-dimensions.\n",
       "numpy.mgrid: Grid-shaped arrays of evenly spaced numbers in N-dimensions.\n",
       ":ref:`how-to-partition`\n",
       "\n",
       "Examples\n",
       "--------\n",
       ">>> np.arange(3)\n",
       "array([0, 1, 2])\n",
       ">>> np.arange(3.0)\n",
       "array([ 0.,  1.,  2.])\n",
       ">>> np.arange(3,7)\n",
       "array([3, 4, 5, 6])\n",
       ">>> np.arange(3,7,2)\n",
       "array([3, 5])\n",
       "\u001b[1;31mType:\u001b[0m      builtin_function_or_method"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# help(np.arange)\n",
    "#或者\n",
    "np.arange?"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b201d546-dce9-49f9-8c32-0bb1730963ba",
   "metadata": {},
   "source": [
    "# 五、数据类型\n",
    "- 数据类型向下取整，取小于x的大整数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "id": "c60b5fc7-3563-48e0-8852-d7cd4547c1b0",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[2.49999 3.5     4.6    ]\n",
      "float32\n",
      "[2 3 4]\n"
     ]
    }
   ],
   "source": [
    "arr5 = np.array([2.49999,3.5,4.6], dtype=np.float32) # 在创建数组时生命其数据类型\n",
    "print(arr5)\n",
    "print(arr5.dtype)\n",
    "\n",
    "print(np.int32(arr5))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d25bf308-1f79-43b5-8ece-6ad8fd9ea654",
   "metadata": {},
   "source": [
    "## 5.1 生成随机数组\n",
    "- np.random.random(n): 在[0,1)中间，生成n个随机数(无约束条件)\n",
    "- np.random.rand(n): 在[0,1)之间，生成n个均匀分布的随机数\n",
    "- np.random.rand(3,4): 生成指定shape的均匀分布随机数，3行4列\n",
    "- np.random.randn(3，4，5): 生成指定shape的正态分布的随机数，\n",
    "- np.random.randint(1,10,(3,4)): 在[1,10)之间，生成3行4列的整数二维数组"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "id": "e881e69e-128e-44ad-9772-f110925f80d0",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0.13532866 0.33790302 0.08069066 0.40388787 0.74054608 0.77565488\n",
      " 0.63908098 0.24442683 0.861735   0.03753312]\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "array([0.3430514 , 0.5328308 , 0.53160321, 0.30438698, 0.56901313,\n",
       "       0.51206742, 0.14352741, 0.43863306, 0.3776596 , 0.47765155])"
      ]
     },
     "execution_count": 51,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "print(np.random.random(10))\n",
    "np.random.rand(10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "id": "0f221b8e-eeb5-46e2-9263-51d19172c99c",
   "metadata": {},
   "outputs": [],
   "source": [
    "# help(np.random.rand)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1ac93642-4f17-4a67-b90d-b09f94fcbc91",
   "metadata": {},
   "source": [
    "## 5.2 random其他函数\n",
    "- seed: 确定随机生成器的种子。\n",
    "- permutation: 返回一个序列的随机排列，或返回一个随机排列的范围。\n",
    "- shuffle: 对一个序列进行随机排序。\n",
    "- binomial: 产生一个二项分布的随机数。\n",
    "- normal: 产生一个正态（高斯）分布的随机数。\n",
    "- beta: 产生beta分布的随机数。\n",
    "- chisquare: 产生卡方分布的随机数。\n",
    "- gamma: 产生gamma分布的随机数。\n",
    "- uniform: 产生在[0,1)中随机分布的随机数。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "534fac8b-1b05-42da-8fec-76a496daf5a8",
   "metadata": {},
   "source": [
    "## 5.3 逻辑索引\n",
    "### 5.3.1 一维数组的索引"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "id": "e36780c4-64be-447c-a1e6-94fb9d697137",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1 3]\n",
      "[False False  True]\n",
      "[3]\n"
     ]
    }
   ],
   "source": [
    "# 数组的逻辑形索引--不常用\n",
    "ls = [1,2,3]\n",
    "arr_ls = np.array(ls)\n",
    "print(arr_ls[[True, False, True]])\n",
    "\n",
    "# 常用\n",
    "index_list = arr_ls>2 # 将数组 ls 中的每一个元素都拿出来和 2 比较，并返回一个布尔值列表\n",
    "print(index_list)\n",
    "print(arr_ls[index_list])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "27979b0a-3ee0-4a85-997e-9a31ddd4338e",
   "metadata": {},
   "source": [
    "### 5.3.2 多维数组的索引"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 80,
   "id": "37701029-43ba-4195-83df-8964145ef397",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 1  2  3  4]\n",
      " [ 5  6  7  8]\n",
      " [ 9 10 11 12]]\n",
      "12\n",
      "[ 9 10 11 12]\n",
      "[ 3  7 11]\n",
      "[[ 6  7]\n",
      " [10 11]]\n",
      "[10]\n",
      "[[ 5  6  7  8]\n",
      " [ 9 10 11 12]]\n"
     ]
    }
   ],
   "source": [
    "# arange(i，j), 左闭右开生成 (i-j) 个数字，和range差不多\n",
    "# reshape(), 重新调整数组的形状，维数，几行几列 \n",
    "arr = np.arange(1,13).reshape([3,4])\n",
    "print(arr)\n",
    "print(arr[2,3])  # 访问第2行第3列的元素12\n",
    "print(arr[2,:])  # 访问第2行的所有数据\n",
    "print(arr[:,2])  # 返回第2列的所有数据\n",
    "print(arr[1:3, 1:3])  # 返回指定行指定列的元素列表，第1行到第2行和第1到第2列的元素数组\n",
    "print(arr[2:, 1])  # 取第二行到末尾行，和第1列的元素数组\n",
    "print(arr[arr[:,0]>4, :])  # 多维数组的逻辑索引，取第0列大于4的行，每行取所有列"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "62c62ba7-63b5-4420-903a-069758263f05",
   "metadata": {},
   "source": [
    "## 5.4 求解距离矩阵"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "200beb6c-49f8-41ee-85b5-b3fe153a739e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[  1.   2.   3.   4.   5.   6.   7.   8.   9.  10.  11.  12.  13.  14.\n",
      "  15.  16.  17.  18.  19.  20.  21.  22.  23.  24.  25.  26.  27.  28.\n",
      "  29.  30.  31.  32.  33.  34.  35.  36.  37.  38.  39.  40.  41.  42.\n",
      "  43.  44.  45.  46.  47.  48.  49.  50.  51.  52.  53.  54.  55.  56.\n",
      "  57.  58.  59.  60.  61.  62.  63.  64.  65.  66.  67.  68.  69.  70.\n",
      "  71.  72.  73.  74.  75.  76.  77.  78.  79.  80.  81.  82.  83.  84.\n",
      "  85.  86.  87.  88.  89.  90.  91.  92.  93.  94.  95.  96.  97.  98.\n",
      "  99. 100.]\n",
      "[  1.   2.   3.   4.   5.   6.   7.   8.   9.  10.  11.  12.  13.  14.\n",
      "  15.  16.  17.  18.  19.  20.  21.  22.  23.  24.  25.  26.  27.  28.\n",
      "  29.  30.  31.  32.  33.  34.  35.  36.  37.  38.  39.  40.  41.  42.\n",
      "  43.  44.  45.  46.  47.  48.  49.  50.  51.  52.  53.  54.  55.  56.\n",
      "  57.  58.  59.  60.  61.  62.  63.  64.  65.  66.  67.  68.  69.  70.\n",
      "  71.  72.  73.  74.  75.  76.  77.  78.  79.  80.  81.  82.  83.  84.\n",
      "  85.  86.  87.  88.  89.  90.  91.  92.  93.  94.  95.  96.  97.  98.\n",
      "  99. 100.]\n",
      "[[  0.           1.41421356   2.82842712 ... 137.17871555 138.59292911\n",
      "  140.00714267]\n",
      " [  1.41421356   0.           1.41421356 ... 135.76450199 137.17871555\n",
      "  138.59292911]\n",
      " [  2.82842712   1.41421356   0.         ... 134.35028843 135.76450199\n",
      "  137.17871555]\n",
      " ...\n",
      " [137.17871555 135.76450199 134.35028843 ...   0.           1.41421356\n",
      "    2.82842712]\n",
      " [138.59292911 137.17871555 135.76450199 ...   1.41421356   0.\n",
      "    1.41421356]\n",
      " [140.00714267 138.59292911 137.17871555 ...   2.82842712   1.41421356\n",
      "    0.        ]]\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "\n",
    "n = 100 # 样本个数\n",
    "x = np.linspace(1, 100, n) # 样本的横坐标\n",
    "y = np.linspace(1, 100, n) # 样本的纵坐标\n",
    "\n",
    "dist = np.zeros([n, n]) # 初始化距离矩阵\n",
    "\n",
    "for i in range(n):\n",
    "    for j in range(n):\n",
    "        dist[i, j] = np.sqrt((x[i]-x[j])**2 + (y[i]-y[j])**2)\n",
    "\n",
    "print(x)\n",
    "print(y)\n",
    "print(dist)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fd8e325d-5f62-4f09-9f67-6d1a223b5a65",
   "metadata": {},
   "source": [
    "## 5.4.1 数组形态变化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "8de18ee0-d66a-4af6-9a5b-f05bfb7aae46",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[ 1  2  3  4  5  6  7  8  9 10 11 12]\n",
      "[[ 1  2  3  4]\n",
      " [ 5  6  7  8]\n",
      " [ 9 10 11 12]]\n",
      "[ 1  2  3  4  5  6  7  8  9 10 11 12]\n",
      "[ 1  2  3  4  5  6  7  8  9 10 11 12]\n",
      "[ 1  5  9  2  6 10  3  7 11  4  8 12]\n"
     ]
    }
   ],
   "source": [
    "arr = np.arange(1, 13) # 生成1-12，12个数\n",
    "print(arr)\n",
    "print(arr.reshape([3, 4]))  # 将一维数组转成，3行列的二维数组\n",
    "\n",
    "arr2 = arr.reshape([3, 4])\n",
    "print(arr2.ravel())  # 将多维数组按行展开成一维数组\n",
    "print(arr2.flatten())  # 将数组按行展开\n",
    "print(arr2.flatten('F'))  # 将数组按列展开\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f7fd63a9-af15-4bed-b6cf-0788990b3c49",
   "metadata": {},
   "source": [
    "## 5.4.2 组合数组"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "93596fbc-6d9a-405d-8f61-f5d37a8c3b83",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 2  3  4  5]\n",
      " [ 6  7  8  9]\n",
      " [10 11 12 13]]\n",
      "[[ 1  2  3  4  2  3  4  5]\n",
      " [ 5  6  7  8  6  7  8  9]\n",
      " [ 9 10 11 12 10 11 12 13]]\n",
      "[[ 1  2  3  4]\n",
      " [ 5  6  7  8]\n",
      " [ 9 10 11 12]\n",
      " [ 2  3  4  5]\n",
      " [ 6  7  8  9]\n",
      " [10 11 12 13]]\n"
     ]
    }
   ],
   "source": [
    "a1 = np.arange(1,13).reshape([3, 4])\n",
    "a2 = np.arange(2,14).reshape([3, 4])\n",
    "print(a2)\n",
    "print(np.hstack((a1, a2)))  # 按照行进组合\n",
    "print(np.vstack((a1, a2)))  # 按照列进行组合"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "430ba5f1-1d54-4aa6-b68f-43eab79da1a5",
   "metadata": {},
   "source": [
    "# 5.5 Numpy矩阵与通用函数"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "278fc27b-7c0e-4055-a2fb-95e1d531d884",
   "metadata": {},
   "source": [
    "### 5.5.1 通用函数\n",
    "- 使用mat函数创建矩阵： matr1 = np.mat(\"1 2 3; 4 5 6; 7 8 9\")\n",
    "- 使用matrix函数创建矩阵：matr2 = np.matrix([[1,2,3], [4,5,6], [7,8,9]])\n",
    "- 使用bmat函数合成矩阵：np.bmat(\"arr1 arr2; arr1, arr2\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "id": "58ee5853-d5a4-4b14-96c4-688969db6940",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[1 2 3]\n",
      " [4 5 6]\n",
      " [7 8 9]]\n",
      "[[3 2 1]\n",
      " [4 5 6]\n",
      " [7 8 9]]\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "array([[1, 2, 3],\n",
       "       [4, 5, 6],\n",
       "       [7, 8, 9]])"
      ]
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "matr1 = np.mat(\"1 2 3; 4 5 6; 7 8 9\")\n",
    "matr2 = np.matrix([[3,2,1], [4,5,6], [7,8,9]])\n",
    "print(matr1)\n",
    "print(matr2)\n",
    "\n",
    "# 合并矩阵\n",
    "np.bmat(\"matr1 matr2; matr1 matr2\")\n",
    "matr1+matr2\n",
    "matr1*matr2\n",
    "np.multiply(matr1, matr2)   # 两个矩阵的对应元素相乘\n",
    "\n",
    "# 其他属性\n",
    "'''\n",
    "T: 返回自身的转置\n",
    "H: 返回自身的共轭转置\n",
    "I: 返回自身的逆矩阵\n",
    "A: 返回自身数据的2维数组的一个视图\n",
    "'''\n",
    "matr1.A"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0e808c54-3043-46cb-a53e-d0d2936d9b18",
   "metadata": {},
   "source": [
    "### 5.5.2 逻辑运算--每个元素依次运算\n",
    "- 四则运算：加（+）减（-）乘（*）除（/）幂（**）。数组间的四则运算表示对每个数组中的元素分别进行四则运算，所以形状(shape)必须相同。\n",
    "- 比较运算，>、<、==、>=、<=、!=。比较运算返回的结果是一个布尔数组，每个元素为每个数组对应元素的比较结果。\n",
    "- 逻辑运算：np.any函数表示逻辑“or”, np.all函数表示逻辑“and”。运算结果返回布尔值。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "9e63053c-eabc-42bc-acac-9bc980089a87",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[ 2 21  4]\n",
      "[ 2 40  6]\n",
      "[7, 8, 9, 7, 8, 9]\n",
      "[ 5 23  6]\n",
      "[ 4 60  9]\n",
      "[False  True  True]\n",
      "[False  True False]\n",
      "True\n",
      "False\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "arr1 = np.array([1,20,3])\n",
    "arr2 = np.array([4,3,3])\n",
    "ls = [7,8,9]\n",
    "# print(arr1)\n",
    "\n",
    "print(arr1 + 1)  # 数组每个元素都 +1\n",
    "# print(ls + 1)    # 报错，非法操作\n",
    "\n",
    "print(arr1 * 2)   # 每个元素都 *2\n",
    "print(ls * 2)     # 注意返回结果\n",
    "\n",
    "print(arr1 + arr2)  # 对应元素相加\n",
    "print(arr1 * arr2)  # 对应元素相乘\n",
    "\n",
    "print(arr1 > 2)     # 每个元素依次比较，返回逻辑数组\n",
    "print(arr1 > arr2)\n",
    "\n",
    "print(np.any(arr1==arr2))  # 对应位置元素进行逻辑或（or）比较\n",
    "print(np.all(arr1==arr2))  # 逻辑与 and\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3b35fc24-250c-4ed9-930d-37aac3f19962",
   "metadata": {},
   "source": [
    "### 5.5.3 广播机制"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "id": "f7af8a8a-9587-4348-ae4f-51b548aaf813",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 1  2  3]\n",
      " [ 4  5  6]\n",
      " [ 7  8  9]\n",
      " [10 11 12]]\n",
      "[1 2 3]\n",
      "[[1]\n",
      " [2]\n",
      " [3]\n",
      " [4]]\n",
      "[[ 2  4  6]\n",
      " [ 5  7  9]\n",
      " [ 8 10 12]\n",
      " [11 13 15]]\n",
      "[[ 2  3  4]\n",
      " [ 6  7  8]\n",
      " [10 11 12]\n",
      " [14 15 16]]\n"
     ]
    }
   ],
   "source": [
    "arr3 = np.arange(1,13).reshape([4,3])        # 4行3列\n",
    "arr4 = np.array([1,2,3])                     # 1行3列\n",
    "arr5 = np.array([1,2,3,4]).reshape([4,1])    # 4行1列\n",
    "print(arr3)\n",
    "print(arr4)\n",
    "print(arr5)\n",
    "\n",
    "print(arr3+arr4)   # arr4广播成4行3列依次与arr3相加\n",
    "print(arr3+arr5)   # arr5广播成4行3列依次与arr3相加\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "id": "d7fd2f78-3b1a-4e34-9849-e63bce541c97",
   "metadata": {},
   "outputs": [],
   "source": [
    "# np.save?"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dd994061-c7dc-4125-826a-f9375d829626",
   "metadata": {},
   "source": [
    "# 5.6 numpy读写文件"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d605f1c1-618a-44f2-8143-b5ac9673dcae",
   "metadata": {},
   "source": [
    "### 5.6.1 读写二进制文件\n",
    "- np.save(\"./tmp/save_arr1.npy\", arr1)  # 以二进制格式保存单个数组数据\n",
    "- np.load(\"./tmp/save_arr1.npy\")        # 以二进制格式读取数据\n",
    "- np.saves(\"./tmp/save_arr1_arr2.npz\", arr1, arr2)  # 将多个数组保存至文件"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "id": "66235add-b990-45b8-8730-aad5caa6490b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 1  2  3]\n",
      " [ 4  5  6]\n",
      " [ 7  8  9]\n",
      " [10 11 12]]\n",
      "[[ 1  2  3  4]\n",
      " [ 5  6  7  8]\n",
      " [ 9 10 11 12]]\n",
      "[[ 1  2  3]\n",
      " [ 4  5  6]\n",
      " [ 7  8  9]\n",
      " [10 11 12]]\n",
      "NpzFile './arr1_arr2.npz' with keys: arr_0, arr_1\n",
      "['arr_0', 'arr_1']\n",
      "[[ 1  2  3]\n",
      " [ 4  5  6]\n",
      " [ 7  8  9]\n",
      " [10 11 12]]\n",
      "[[ 1  2  3  4]\n",
      " [ 5  6  7  8]\n",
      " [ 9 10 11 12]]\n"
     ]
    }
   ],
   "source": [
    "arr1 = np.arange(1,13).reshape([4,3])\n",
    "arr2 = np.arange(1,13).reshape([3,4])\n",
    "\n",
    "print(arr1)\n",
    "print(arr2)\n",
    "\n",
    "np.save('./arr1.npy', arr1)               # 保存数组\n",
    "arr1_load = np.load('./arr1.npy')         # 读取数据\n",
    "print(arr1_load)\n",
    "\n",
    "np.savez('./arr1_arr2.npz', arr1, arr2)   # 保存多个数据\n",
    "arr1_arr2_load = np.load('./arr1_arr2.npz')\n",
    "\n",
    "print(arr1_arr2_load)            # 打印的是一个文件地址\n",
    "print(arr1_arr2_load.files)      # 查看数据文件中有哪些数组对象\n",
    "print(arr1_arr2_load['arr_0'])   # 访问数据文件中的具体数组对象\n",
    "print(arr1_arr2_load['arr_1'])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bc349032-bc0d-4e36-95e6-d12b645b21c2",
   "metadata": {},
   "source": [
    "# 5.6.2 读写文本文件\n",
    "- np.savetxt('./tmp/arr.txt', arr, fmt='%d', delimiter=',')  # 将数组写到某种分隔符隔开的文本文件中\n",
    "- np.loadtxt('./tmp/arr.txt', delimiter=',')    # 把文件加载到一个二维数组中\n",
    "- np.genfromtxt('./tmp/arr.txt', delimiter=',')  # 此函数面向的是结构化数组和缺失数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "id": "7aca2a20-988b-4602-a5ad-9b3467582470",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 1  2  3]\n",
      " [ 4  5  6]\n",
      " [ 7  8  9]\n",
      " [10 11 12]]\n"
     ]
    }
   ],
   "source": [
    "np.savetxt('./arr1.txt', arr1, fmt='%d', delimiter=',')            # 默认以18位浮点数存储\n",
    "arr1_load = np.loadtxt('./arr1.txt',dtype='int', delimiter=',')    # 读取的结果以浮点数保存\n",
    "print(arr1_load)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3e5ff3d1-6c14-4384-9547-1d88422a3c6b",
   "metadata": {},
   "source": [
    "# 六、使用数组进行简单的统计分析"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 102,
   "id": "da331670-5188-489b-8fff-355c2e2c365c",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[2 2 9 8]\n",
      " [4 5 4 8]\n",
      " [4 9 3 1]]\n",
      "[[2 2 3 1]\n",
      " [4 5 4 8]\n",
      " [4 9 9 8]]\n",
      "[[1 2 2 3]\n",
      " [4 4 5 8]\n",
      " [4 8 9 9]]\n",
      "[[0 0 0 0]\n",
      " [1 1 1 1]\n",
      " [2 2 2 2]]\n",
      "[[1 2 2 3 1 2 2 3]\n",
      " [4 4 5 8 4 4 5 8]\n",
      " [4 8 9 9 4 8 9 9]]\n",
      "[[1 1 2 2 2 2 3 3]\n",
      " [4 4 4 4 5 5 8 8]\n",
      " [4 4 8 8 9 9 9 9]]\n",
      "4.916666666666667\n",
      "[3.         4.66666667 5.33333333 6.66666667]\n",
      "[[6 2 8 4]\n",
      " [6 6 2 5]\n",
      " [1 7 3 2]]\n",
      "[6 7 8 5]\n",
      "[8 6 7]\n",
      "[0 2 0 1]\n"
     ]
    }
   ],
   "source": [
    "arr = np.random.randint(1, 10, [3,4])\n",
    "# arr = np.array([2,3,5,1,8,3,6,3,7,3,2,0]).reshape([3,4])\n",
    "print(arr)\n",
    "\n",
    "arr.sort(axis=0)  # 对数组元素按大小进行排序 (按列排序)\n",
    "print(arr)\n",
    "arr.sort(axis=1)  # 对数组元素按大小进行排序 (按行排序)\n",
    "print(arr)\n",
    "print(arr.argsort(axis=0))   # 返回排序后的下标\n",
    "\n",
    "print(np.tile(arr, 2))       # 对数组进行复制\n",
    "print(np.repeat(arr, 2,axis=1))  # 对数组元素进行复制\n",
    "\n",
    "print(arr.mean())   # 统计数组所有元素的平均值\n",
    "print(arr.mean(axis=0)) # 案列统计数组的均值\n",
    "\n",
    "arr = np.random.randint(1, 10, [3,4])\n",
    "print(arr)\n",
    "print(arr.max(axis=0))  # 按列统计最大值\n",
    "print(arr.max(axis=1))  # 按行统计最大值\n",
    "\n",
    "print(arr.argmax(axis=0))  # 找出每列元素最大值的位置"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "838336e9-1e39-4259-b97b-2035d3c344aa",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
